/*
 * Copyright 2011 Clean GWT
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.cleangwt.bootstrap.client.ui;

import com.cleangwt.user.client.Elements;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.user.client.ui.SimplePanel;

/**
 * The small overlays of content, like those on the iPad, to any element for housing secondary
 * information.
 * 
 * @author Jess
 * @version 1.0
 * @since 1.0
 * @see http://getbootstrap.com/javascript/#popovers
 */
public class Popover extends SimplePanel {
  /**
   * The type for popover.
   */
  public enum PopoverType {
    BOTTOM("bottom"), LEFT("left"), RIGHT("right"), TOP("top");

    String value;

    /**
     * Defines a popover type by the specified value.
     */
    PopoverType(String value) {
      this.value = value;
    }
  }

  private static final String DEFAUL_STYLENAME = "popover";
  private static final String ARROW_STYLE = "arrow";
  private static final String CONTENT_STYLE = "popover-content";
  private static final String TITLE_STYLE = "popover-title";

  /**
   * Activates the given popover-toggle element.
   * 
   * @param e popover-toggle element.
   */
  public static native void activate(Element e) /*-{
                                                $wnd.jQuery(e).popover();
                                                }-*/;

  /**
   * Activates the given popover-toggle element with the given title and message.
   * 
   * @param e popover-toggle element.
   * @param title the title
   * @param message the message
   */
  public static void activate(Element e, String title, String message) {
    activate(e, title, message, PopoverType.RIGHT, false);
  }

  /**
   * Activates the given popover-toggle element with the given title, message and 'addToBody' option
   * .
   * 
   * @param e popover-toggle element.
   * @param title the title
   * @param message the message
   * @param addToBody whether to add the popover to body, false to add popover to the parent of
   *          toggle
   */
  public static void activate(Element e, String title, String message, PopoverType type,
      boolean addToBody) {
    e.setAttribute(DataModel.DATA_TOGGLE, DataModel.TOGGLE_POPOVER);
    e.setAttribute(DataModel.DATA_ORIGINAL_TITLE, title);
    e.setAttribute(DataModel.DATA_CONTENT, message);
    e.setAttribute(DataModel.DATA_PLACEMENT, type.value);
    if (addToBody) {
      e.setAttribute(DataModel.DATA_CONTAINER, "body");
    }
    activate(e);
  }

  public static native void destroy(Element e) /*-{
                                               $wnd.jQuery(e).popover('destroy');
                                               }-*/;

  public static native void hide(Element e) /*-{
                                            $wnd.jQuery(e).popover('hide');
                                            }-*/;

  public static native void show(Element toggle) /*-{
                                                 $wnd.jQuery(toggle).popover('show');
                                                 }-*/;

  public static native void toggle(Element e) /*-{
                                              $wnd.jQuery(e).popover('toggle');
                                              }-*/;

  /**
   * Creates a popover with the given message and popover type.
   * 
   * @param message the message
   * @param type the popover type
   */
  public Popover(String message, PopoverType type) {
    this(message, null, type);
  }

  /**
   * Creates a popover with the given message, title and the default popover type.
   * 
   * @param message the message
   * @param title the title
   */
  public Popover(String message, String title) {
    this(message, title, PopoverType.RIGHT);
  }

  /**
   * Creates a popover with the given message, title and popover type.
   * 
   * @param message the message
   * @param title the title
   * @param type the popover type
   */
  public Popover(String message, String title, PopoverType type) {
    this.setStyleName(DEFAUL_STYLENAME);
    // the custom popover with block-display and relative-position
    this.getElement().getStyle().setDisplay(Display.BLOCK);
    this.getElement().getStyle().setPosition(Position.RELATIVE);
    this.addStyleName(type.value);
    // title
    if (title != null) {
      Element header = Document.get().createDivElement();
      header.setInnerHTML(title);
      header.setClassName(TITLE_STYLE);
      this.getElement().appendChild(header);
    }
    // arrow
    Element arrow = Document.get().createDivElement();
    this.getElement().appendChild(arrow);
    arrow.setClassName(ARROW_STYLE);
    // content
    Element contentDiv = Document.get().createDivElement();
    this.getElement().appendChild(contentDiv);
    contentDiv.setInnerHTML(message);
    contentDiv.setClassName(CONTENT_STYLE);
  }

  @SuppressWarnings("deprecation")
  @Override
  protected com.google.gwt.user.client.Element getContainerElement() {
    return Elements.getByClass(getElement(), CONTENT_STYLE).cast();
  }

}
